package com.ceuer.resttemplate.config;

import okhttp3.OkHttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfig {
	
	/**
	 * 没有实例化RestTemplate时，初始化RestTemplate
	 * @return
	 */
	@ConditionalOnMissingBean(RestTemplate.class)
	@Bean
	public RestTemplate restTemplate() {
		/*
		//这种初始化方法，是使用了JDK自带的HttpURLConnection作为底层HTTP客户端实现。
		RestTemplate restTemplate = new RestTemplate();
		*/
		
		/*
		//还可以修改RestTemplate默认的客户端，例如将其改成HttpClient客户端，方式如下
		RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactoryForHttpClient());
		*/
		
		//还可以修改RestTemplate默认的客户端，例如将其改成OkHttp客户端，方式如下
		RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactoryForOkHttp());
		return restTemplate;
	}
	
	/**
	 * 使用HttpClient作为底层客户端
	 * @return
	 */
	private ClientHttpRequestFactory getClientHttpRequestFactoryForHttpClient() {
		int timeout = 5*1000;//5秒
		RequestConfig config = RequestConfig.custom()
				.setConnectTimeout(timeout)//连接超时时间
				.setConnectionRequestTimeout(timeout)//连接不够用的等待时间
				.setSocketTimeout(timeout)
				.build();
		CloseableHttpClient client = HttpClientBuilder
				.create()
				.setDefaultRequestConfig(config)
				.setMaxConnTotal(100)//最大连接数
				.setMaxConnPerRoute(20)//同路由并发数
				.build();
		return new HttpComponentsClientHttpRequestFactory(client);
	}
	
	/**
	 * 使用OkHttpClient作为底层客户端
	 * @return
	 */
	private ClientHttpRequestFactory getClientHttpRequestFactoryForOkHttp(){
		OkHttpClient okHttpClient = new OkHttpClient.Builder()
				.connectTimeout(5, TimeUnit.SECONDS)
				.writeTimeout(5, TimeUnit.SECONDS)
				.readTimeout(5, TimeUnit.SECONDS)
				.build();
		return new OkHttp3ClientHttpRequestFactory(okHttpClient);
	}
}
